using System;
using System.Collections.Generic;
using System.Text;

namespace TVDesigner.Generator.Components
{
    public class Screen : GenericComponent
    {
        private List<GenericComponent> _Components;	

        public List<GenericComponent> Components
        {
            get { return _Components; }
            set { _Components = value; }
        }

        private string _ScreenBlue;
        private string _ScreenYellow;
        private string _ScreenRed;
        private string _ScreenGreen;

        public string ScreenGreen
        {
            get { return _ScreenGreen; }
            set { _ScreenGreen = value; }
        }
        public string ScreenRed
        {
            get { return _ScreenRed; }
            set { _ScreenRed = value; }
        }
        public string ScreenYellow
        {
            get { return _ScreenYellow; }
            set { _ScreenYellow = value; }
        }
        public string ScreenBlue
        {
            get { return _ScreenBlue; }
            set { _ScreenBlue = value; }
        }

        public override string TypeString
        {
            get { return NameStartedWithUpperCase; }
        }

        public Screen()
        {
            _Components = new List<GenericComponent>();
        }

        #region Method used
        protected override void SetAtributes(StringBuilder sb)
        {

        } 
        #endregion

        public string DeclareClass(string package, string xletName)
        {
            StringBuilder sb = new StringBuilder();

            //package
            if (package != null && !package.Equals(string.Empty))
            {
                sb.Append("package ").Append(package).Append(";\n\n");
            }

            //imports.
            sb.Append("import org.havi.ui.HContainer;\n\n");

            //class declaration.
            sb.Append("public class ").Append(NameStartedWithUpperCase).Append(" extends HContainer implements TVDesignerScreen {\n");

            sb.Append("\n");
            //atributes
            LoadAtributesDeclaration(sb, xletName);
            sb.Append("\n");

            //constructors.
            LoadConstructor(sb, xletName);
            sb.Append("\n");

            //methods.
            LoadMethods(sb, xletName);
            sb.Append("\n");

            sb.Append("}\n");

            return sb.ToString();
        }

        #region Private Methods used to declare a Screen class.
        private void LoadAtributesDeclaration(StringBuilder sb, string xletName)
        {
            sb.Append("\tprotected ").Append(xletName).Append(" xlet;\n");
			sb.Append("\tprivate org.havi.ui.HIcon[] focusableButtons;\n");
			sb.Append("\tprivate int count;\n");
            foreach (GenericComponent gc in _Components)
            {
                sb.Append(gc.AtributeDeclaration);
            }
        }

        private void LoadConstructor(StringBuilder sb, string xletName)
        {
            sb.Append("\tpublic ").Append(NameStartedWithUpperCase).Append("(").Append(xletName).Append(" xlet ){\n");
            sb.Append("\t\tsuper();\n");
            sb.Append("\t\tthis.xlet = xlet;\n");
            sb.Append("\t\tthis.init();\n");
            sb.Append("\t}\n");
        }

        private void LoadMethods(StringBuilder sb, string xletName)
        {
            this.LoadInitMethod(sb);
            sb.Append("\n");

            foreach (GenericComponent gc in _Components)
            {
                sb.Append(gc.MethodDeclaration);
                sb.Append("\n");
            }

            //metodos da interface TVDesignerScreen.
            this.LoadKeyEventHandlerMethod(sb, xletName);
            sb.Append("\n");
            this.LoadSetXlet(sb, xletName);
            sb.Append("\n");
            this.LoadSetVisible(sb);
            sb.Append("\n");
        }

        private void LoadSetVisible(StringBuilder sb)
        {
            sb.Append("\tpublic void setVisible(boolean visible) {\n");
            sb.Append("\t\tsuper.setVisible(visible);\n");
            sb.Append("\t\tthis.requestFocus();\n");
            sb.Append("\t\tif (this.focusableButtons != null && this.count >= 0 && this.count < this.focusableButtons.length) {\n"); 
            sb.Append("\t\t\tthis.focusableButtons[count].requestFocus();\n");
            sb.Append("\t\t}\n");
            sb.Append("\t}\n");
        }

        private void LoadSetXlet(StringBuilder sb, string xletName)
        {
            sb.Append("\tpublic void setXlet(").Append(xletName).Append(" xlet) {\n");
            sb.Append("\t\tthis.xlet = xlet;\n");
            sb.Append("\t}");
        }

        private void LoadKeyEventHandlerMethod(StringBuilder sb, string xletName)
        {
            sb.Append("\tpublic void keyEvent(java.awt.event.KeyEvent event) {\n");

			int i = 0;

			sb.Append("\t\tswitch(event.getKeyCode()){\n");

			//enter
			sb.Append("\t\t\tcase java.awt.event.KeyEvent.VK_ENTER: {\n");
			foreach (GenericComponent gc in this._Components) {
				if (gc.GetType() == typeof(HButton)) {
					HButton hb = (HButton)gc;
					if (hb.HScreenName != null) {
                        string screenStaticNumberName = Generator.Instance.ProjectXlet.StaticScreenStringName[hb.HScreenName];
                        string value = string.Concat(Generator.Instance.Instructions.ProjectNameStartedWithUpperCase, ".", screenStaticNumberName); 

						sb.Append("\t\t\t\tif (this.count == ").Append(i.ToString()).Append(") {\n");
                        sb.Append("\t\t\t\t\tthis.xlet.setCurrentScreen(").Append(value).Append(");\n");
                        sb.Append("\t\t\t\t\treturn;\n");
						sb.Append("\t\t\t\t}\n");
					}
                    i++;
				}
			}
            sb.Append("\t\t\t\tbreak;\n");
            sb.Append("\t\t\t}\n");

            //teclas coloridas
            sb.Append("\t\t\tcase TVDesignerKeyListener.KEY_RED: {\n");
            if (_ScreenRed != null)
            {
                sb.Append("\t\t\t\tthis.xlet.setCurrentScreen(").Append(xletName).Append(".").Append(_ScreenRed.ToUpper()).Append(");\n");
                sb.Append("\t\t\t\treturn;\n");
            }
            sb.Append("\t\t\t}\n");
            sb.Append("\t\t\tcase TVDesignerKeyListener.KEY_GREEN: {\n");
            if (_ScreenGreen != null)
            {
                sb.Append("\t\t\t\tthis.xlet.setCurrentScreen(").Append(xletName).Append(".").Append(_ScreenGreen.ToUpper()).Append(");\n");
                sb.Append("\t\t\t\treturn;\n");
            }
            sb.Append("\t\t\t}\n");
            sb.Append("\t\t\tcase TVDesignerKeyListener.KEY_YELLOW: {\n");
            if (_ScreenYellow != null)
            {
                sb.Append("\t\t\t\tthis.xlet.setCurrentScreen(").Append(xletName).Append(".").Append(_ScreenYellow.ToUpper()).Append(");\n");
                sb.Append("\t\t\t\treturn;\n");
            }
            sb.Append("\t\t\t}\n");
            sb.Append("\t\t\tcase TVDesignerKeyListener.KEY_BLUE: {\n");
            if (_ScreenBlue != null)
            {
                sb.Append("\t\t\t\tthis.xlet.setCurrentScreen(").Append(xletName).Append(".").Append(_ScreenBlue.ToUpper()).Append(");\n");
                sb.Append("\t\t\t\treturn;\n");
            }
            sb.Append("\t\t\t}\n");
			
			//para cima
			sb.Append("\t\t\tcase java.awt.event.KeyEvent.VK_UP: {\n");
            sb.Append("\t\t\t\tif (this.focusableButtons == null) {\n");
            sb.Append("\t\t\t\t\treturn;\n");
            sb.Append("\t\t\t\t}\n");
			sb.Append("\t\t\t\tthis.count--;\n");
            sb.Append("\t\t\t\tif(this.count < 0)\n");
            sb.Append("\t\t\t\t\tthis.count = this.focusableButtons.length-1;\n");
			sb.Append("\t\t\t\tthis.focusableButtons[this.count].requestFocus();\n");
			sb.Append("\t\t\t\tbreak;\n");
            sb.Append("\t\t\t}\n");

			//pra baixo
			sb.Append("\t\t\tcase java.awt.event.KeyEvent.VK_DOWN: {\n");
            sb.Append("\t\t\t\tif (this.focusableButtons == null) {\n");
            sb.Append("\t\t\t\t\treturn;\n");
            sb.Append("\t\t\t\t}\n");
            sb.Append("\t\t\t\tthis.count = (++this.count)%this.focusableButtons.length;\n");
            sb.Append("\t\t\t\tthis.focusableButtons[this.count].requestFocus();\n");
			sb.Append("\t\t\t\tbreak;\n");
            sb.Append("\t\t\t}\n");

			//escape
			sb.Append("\t\t\tcase java.awt.event.KeyEvent.VK_ESCAPE: {\n");
            sb.Append("\t\t\t\tif (this.xlet.getPreviousScreen() != null) {\n");
			sb.Append("\t\t\t\t\tthis.xlet.setCurrentScreen(this.xlet.getPreviousScreen());\n");
			sb.Append("\t\t\t\t}\n");
			sb.Append("\t\t\t\tbreak;\n");
            sb.Append("\t\t\t}\n");

            sb.Append("\t\t}\n");
            sb.Append("\t}\n");
        }

        private void LoadInitMethod(StringBuilder sb)
        {
			int sizeArray = 0;
			sb.Append("\tprotected void init() {\n");
            //loading the values.

            sb.Append("\t\tthis.setVisible(false);\n");
            sb.Append("\t\tthis.setLocation(").Append(this.Location.X).Append(", ").Append(this.Location.Y).Append(");\n");
            sb.Append("\t\tthis.setSize(").Append(this.Size.Width).Append(", ").Append(this.Size.Height).Append(");\n");
            sb.Append("\n");

            //adding the components.
            foreach (GenericComponent gc in _Components)
            {
                sb.Append("\t\tthis.add(").Append(gc.MethodCall).Append(");\n");
				if (gc.GetType() == typeof(HButton) && gc.Focusable) {
					sizeArray++;
				}
                if (gc is HButton)
                {
                    sb.Append("\t\tthis.").Append(gc.MethodCall).Append(".addKeyListener(this.xlet.getListener());\n");
                }
            }

            sb.Append("\t\tthis.addKeyListener(this.xlet.getListener());\n");

            if (sizeArray > 0)
            {
                sb.Append("\n");
                //botoes com focusable

                sb.Append("\t\tthis.focusableButtons = new org.havi.ui.HIcon[").Append(sizeArray).Append("];\n\n");
                int i = 0;
                foreach (GenericComponent gc in _Components)
                {
                    if (gc.GetType() == typeof(HButton) && gc.Focusable)
                    {
                        sb.Append("\t\tthis.focusableButtons[").Append(i).Append("] = ").Append(gc.MethodCall).Append(";\n");
                        i++;
                    }
                }

                sb.Append("\n");
                sb.Append("\t\tthis.focusableButtons[0].requestFocus();\n");
            }

            sb.Append("\t}\n");
        }

        public string AtributeDeclaration
        {
            get
            {
                return
                    string.Concat("\tprivate ", TypeString, " ", _Name, " = new ", TypeString, "();\n");
            }
        }
        #endregion

        #region override
        public override bool Equals(object obj)
        {
            if (obj != null && obj.GetType() == this.GetType())
            {
                return (((Screen)obj).Name.Equals(this.Name));
            }
            return false;
        }
        #endregion
    }
}
